<?php
/*
 * This file is part of the BooXtore Student project.
 *
 * (c) Francis Backeland f.backeland@gmail.com
 * (c) Laurine Chaplot chaplot.laurine@orange.fr
 * (c) Julien Dutot julien.dutot@gmail.com
 * (c) Romain Guillaume romain-guillaume@orange.fr
 * (c) Guillaume Paringaux g.paringaux@gmail.com
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code
 */

namespace BXTR\DatatablesBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use BXTR\DatatablesBundle\Form\DataTransformer\EntityToNumberTransformer;
use Symfony\Component\PropertyAccess\PropertyAccess;

/** 
 * DataTables Entity Selector Form Type.
 * 
 * This form takes an ArrayCollection from Doctrine and display it in an HTML 
 * table useable with the DataTables jQuery plugin.
 *
 * The selection can be handled with DatatableSubmitType(s).
 *
 * This form extends the hidden FormType
 *
 * The output is the user selected element of the ArrayCollection provided 
 * in options 
 *
 * /!\ Warning: /!\ 
 * The javasript file:"BXTR/DataTablesBundle/Ressources/js/DatatablesIntegration.js" 
 * And the Css file : "BXTR/DataTablesBundle/Ressources/less/DatatablesIntegration.css" 
 * has to be loaded in the page for the table to be rendered correctly.
 *
 * The view is defined in BXTRDatatableBundle:Form:fields.html.twig
 */
class DatatablesSelectorType extends AbstractType
{
    /**
     * Bind an EntityToNumberTransformer to the form.
     *
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new EntityToNumberTransformer($options['query_builder']);
        $builder->addModelTransformer($transformer);
    }

    /**
     * Extends the hidden FormType
     */
    public function getParent()
    {
        return 'text';
    }

    /**
     * Form clean name : datatables_selector
     *
     */
    public function getName()
    {
        return 'datatables_selector';
    }

    /**
     * This form has three options fields :
     * - collection: An ArrayCollection of entities, typically the result of a doctrine query.
     * - index_field: A String containing the name of the property/method used on entities to identify the selection.
     * - fields: An Array<String> containing the name of the fields to show in the table.
     *
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'fieldLabels' => array(),
            'fieldTransformers' => array(),
            //'mapped' => false,
        ));

        $resolver->setRequired(array(
            'query_builder',
            'fieldNames',
            'class',
        ));
    }

    /**
     * Add serevals vars to the views :
     * - table_entities: the ArrayCollection of entities provided in the collection option.
     * - table_fields: the Array provided in the field option. 
     * - table_index_field: The String provided in the index_field option.
     *
     * @param FormView $view
     * @param FormInterface $form
     * @param Array $options
     */
    public function buildView(FormView $view, FormInterface $form, Array $options)
    {
        $accessor = PropertyAccess::createPropertyAccessor();
        $collection = $options['query_builder']->getQuery()->getResult();

        $qb = $options['query_builder'];
        $em = $qb->getEntityManager();
        $indexField = $em->getClassMetadata($options['class'])->identifier[0];

        $values = array();
        foreach ($collection as $entity) {
            $fieldValues = array();
            foreach($options['fieldNames'] as $fieldName) {
                $value = $accessor->getValue($entity, $fieldName);
                $transformerName = (array_key_exists($fieldName, $options['fieldTransformers']))?$options['fieldTransformers'][$fieldName]:null;
                if ($transformerName !== null) {
                    $transformer = new $transformerName();
                    $value = $transformer->transform($value);
                }
                $fieldValues[] = $value;
            }
            
            $values[] = array(
                'identifier' => $accessor->getValue($entity, $indexField),
                'values' => $fieldValues
            );
        }

        $view->vars['table_values'] = $values;
        //$view->vars['table_fields'] = $options['fieldNames'];
        $view->vars['table_labels'] = array_merge($this->buildLabelList($options['fieldNames'], $options['class']), $options['fieldLabels']);
        

        
    }
    
    protected function buildLabelList($fieldNames, $class)
    {
        $labelList = array();
        foreach($fieldNames as $field)
        {
            $labelList[$field] = null;//'Ent.' . substr(strrchr($class, '\\'), 1) . '.Fields.' . Inflector::camelize $field; 
        }
        return $labelList;
    }
};
